package middleware

import (
	"backEnd/common"
	"backEnd/model"
	"fmt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

func UserAuthMiddleware() gin.HandlerFunc { //登录认证
	return func(ctx *gin.Context) {
		// 获取 authorization header
		tokenString := ctx.GetHeader("Authorization")

		//验证token格式
		if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") {
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token格式错误",
			})
			ctx.Abort()
			return
		}

		tokenString = tokenString[7:] //截取字符

		token, claims, err := common.ParseToken(tokenString)

		if err != nil || !token.Valid {
			fmt.Print("token出现错误:", tokenString, "\n")

			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token解析失败",
			})
			ctx.Abort()
			return
		}

		//token通过验证, 获取claims中的UserID
		userId := claims.ID
		DB := common.GetDB()
		var user model.User
		DB.First(&user, userId)

		// 验证用户是否存在
		if user.ID == 0 {
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "用户不存在",
			})
			ctx.Abort()
			return
		}

		//用户存在 将user信息写入上下文
		ctx.Set("user", user)

		ctx.Next()
	}
}

func VerifyAuthMiddleware() gin.HandlerFunc { // 验证码认证
	return func(ctx *gin.Context) {
		// 获取 authorization header
		tokenString := ctx.GetHeader("Authorization")

		//验证token格式
		if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") {
			fmt.Print("注册用token出现错误:", tokenString, "\n")
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token格式错误",
			})
			ctx.Abort()
			return
		}

		tokenString = tokenString[7:] //截取字符

		token, claims, err := common.ParseToken(tokenString)

		if err != nil || !token.Valid {
			fmt.Print("注册用token出现错误:", tokenString, "\n")
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token不合法",
				"err":  err,
			})
			ctx.Abort()
			return
		}

		//token通过验证, 获取claims中的Telephone
		Telephone := claims.Telephone
		DB := common.GetDB()
		var verification model.VerificationCode
		DB.Where("telephone = ?", Telephone).First(&verification)

		//将verificationCode信息写入上下文
		ctx.Set("verificationCode", verification)

		ctx.Next()
	}
}

func AdminAuthMiddleware() gin.HandlerFunc { // 管理员认证
	return func(ctx *gin.Context) {
		// 获取 authorization header
		tokenString := ctx.GetHeader("Authorization")

		fmt.Print("验证请求token:", tokenString, "\n")

		//验证token格式
		if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") {
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token格式错误",
			})
			ctx.Abort()
			return
		}

		tokenString = tokenString[7:] //截取字符

		token, claims, err := common.ParseToken(tokenString)

		if err != nil || !token.Valid {
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token不合法",
				"err":  err,
			})
			ctx.Abort()
			return
		}

		//token通过验证, 获取claims中的Telephone
		Telephone := claims.Telephone
		DB := common.GetDB()
		var verification model.VerificationCode
		DB.Where("telephone = ?", Telephone).First(&verification)

		//将verificationCode信息写入上下文
		ctx.Set("Admin", verification)

		ctx.Next()
	}
}
